/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.inspur.edp.formserver.vmmanager.createvmmetadata;


import com.inspur.edp.cef.designtime.api.operation.CommonDetermination;
import com.inspur.edp.cef.designtime.api.util.DataValidator;
import com.inspur.edp.cef.designtime.api.variable.CommonVariableEntity;
import com.inspur.edp.cef.variable.dtgenerator.vardtmGenerate.cmpgenerators.CommonDtmGenerator;
import com.inspur.edp.formserver.viewmodel.GspViewModel;
import com.inspur.edp.formserver.viewmodel.action.MappedCdpAction;
import com.inspur.edp.formserver.viewmodel.action.ViewModelAction;
import com.inspur.edp.formserver.viewmodel.action.ViewModelActionType;
import com.inspur.edp.formserver.viewmodel.collection.VMActionCollection;
import com.inspur.edp.formserver.viewmodel.common.ValueHelpConfig;
import com.inspur.edp.formserver.viewmodel.dataextendinfo.VoDataExtendInfo;
import com.inspur.edp.lcm.metadata.api.entity.MetadataProject;
import com.inspur.edp.lcm.metadata.api.service.MetadataProjectService;
import io.iec.edp.caf.commons.utils.SpringBeanUtils;
import io.iec.edp.caf.commons.utils.StringUtils;

import java.util.ArrayList;

public class ComponentGenerator {
    public static final String ComponentDir = "component";

    public static ComponentGenerator getInstance() {
        return new ComponentGenerator();
    }

    private ComponentGenerator() {
        createComponentActionList = new ArrayList();
    }

    private ArrayList createComponentActionList;
    /**
     * VM的编号
     */
    private String privateVMActionCode;

    private String getVMActionCode() {
        return privateVMActionCode;
    }

    private void setVMActionCode(String value) {
        privateVMActionCode = value;
    }

    /**
     * VM变量实体的编号
     */
    private String privateVMVariableEntityCode;

    private String getVMVariableEntityCode() {
        return privateVMVariableEntityCode;
    }

    private void setVMVariableEntityCode(String value) {
        privateVMVariableEntityCode = value;
    }

    /**
     * VM的程序集名称
     */
    private String privateAssemblyName;

    private String getAssemblyName() {
        return privateAssemblyName;
    }

    private void setAssemblyName(String value) {
        privateAssemblyName = value;
    }

    private String privateNamespace;

    private String getNamespace() {
        return privateNamespace;
    }

    private void setNamespace(String value) {
        privateNamespace = value;
    }

    /**
     * 业务对象ID
     */
    private String privateBizObjectID;

    private String getBizObjectID() {
        return privateBizObjectID;
    }

    private void setBizObjectID(String value) {
        privateBizObjectID = value;
    }

    public final ArrayList GenerateComponent(GspViewModel viewModel, String path, String bizObjectID) {
        // 参数校验
        DataValidator.checkForNullReference(viewModel, "viewModel");
        DataValidator.checkForEmptyString(path, "path");

        MetadataProject metadataProj = SpringBeanUtils.getBean(MetadataProjectService.class).getMetadataProjInfo(path);
        setAssemblyName(metadataProj.getCsprojAssemblyName());
        setNamespace(metadataProj.getNameSpace());
        DataValidator.checkForEmptyString(getAssemblyName(), "AssemblyName");
        setVMActionCode(viewModel.getCode());
        DataValidator.checkForEmptyString(getVMActionCode(), "VMActionCode");
        setBizObjectID(bizObjectID);
        String cmpPath = ComponentGenUtil.prepareComponentDir(path);

        generateViewModelActionComponents(viewModel, cmpPath);
        generateVariableDtmComponents(viewModel, cmpPath);
        return this.createComponentActionList;
    }

    /**
     * 变量联动计算
     *
     * @param viewModel
     * @param path
     */
    private void generateVariableDtmComponents(GspViewModel viewModel, String path) {
        if (viewModel.getVariables() == null) {
            return;
        }

        CommonVariableEntity cdtDef = viewModel.getVariables();
        setVMVariableEntityCode(cdtDef.getCode());
        for (CommonDetermination dtmInfo : cdtDef.getDtmBeforeSave()) {
            if (dtmInfo.getIsRef() || !dtmInfo.getIsGenerateComponent()) {
                continue;
            }
            setNewCompActionCode(
                    CommonDtmGenerator.getInstance().GenerateComponent(viewModel, dtmInfo, path, this.getVMVariableEntityCode(), this.getAssemblyName(), getNamespace(), this.getBizObjectID()));

        }
        for (CommonDetermination dtmInfo : cdtDef.getDtmAfterCreate()) {
            if (dtmInfo.getIsRef() || !dtmInfo.getIsGenerateComponent()) {
                continue;
            }
            setNewCompActionCode(CommonDtmGenerator.getInstance().GenerateComponent(viewModel, dtmInfo, path, this.getVMVariableEntityCode(), this.getAssemblyName(), getNamespace(), this.getBizObjectID()));
        }
        for (CommonDetermination dtmInfo : cdtDef.getDtmAfterModify()) {
            if (dtmInfo.getIsRef() || !dtmInfo.getIsGenerateComponent()) {
                continue;
            }
            setNewCompActionCode(CommonDtmGenerator.getInstance().GenerateComponent(viewModel, dtmInfo, path, this.getVMVariableEntityCode(), this.getAssemblyName(), getNamespace(), this.getBizObjectID()));
        }
    }

    /** 视图对象上的视图操作、扩展操作、帮助前
     * @param viewModel BE实体
     * @param path      生成路径
     */
    private void generateViewModelActionComponents(GspViewModel viewModel, String path) {
        //视图操作构件元数据
        for (ViewModelAction action : viewModel.getActions()) {
            if (action.getType() == ViewModelActionType.VMAction && ((MappedCdpAction)action).getIsGenerateComponent()) {
                setNewCompActionCode(MappedCdpActionComponentGenerator.getInstance().generateVMComponent((MappedCdpAction) action, path, this.getVMActionCode(), this.getAssemblyName(), getNamespace(), this.getBizObjectID()));

            }

        }

        ArrayList<VMActionCollection> list = new ArrayList<>();
        VoDataExtendInfo extendInfo = viewModel.getDataExtendInfo();
        list.add(extendInfo.getAfterCreateActions());
        list.add(extendInfo.getAfterModifyActions());
        list.add(extendInfo.getAfterQueryActions());
        list.add(extendInfo.getAfterRetrieveActions());
        list.add(extendInfo.getAfterSaveActions());
        list.add(extendInfo.getBeforeCreateActions());
        list.add(extendInfo.getBeforeDeleteActions());
        list.add(extendInfo.getBeforeQueryActions());
        list.add(extendInfo.getBeforeRetrieveActions());
        list.add(extendInfo.getBeforeSaveActions());
        list.add(extendInfo.getSaveActions());
        list.add(extendInfo.getChangesetMappingActions());
        list.add(extendInfo.getChangesetReversalMappingActions());
        list.add(extendInfo.getCreateActions());
        list.add(extendInfo.getDataMappingActions());
        list.add(extendInfo.getDataReversalMappingActions());
        list.add(extendInfo.getDeleteActions());
        list.add(extendInfo.getModifyActions());
        list.add(extendInfo.getQueryActions());
        list.add(extendInfo.getRetrieveActions());
        list.add(extendInfo.getAfterDeleteActions());
        list.add(extendInfo.getBeforeModifyActions());
        list.add(extendInfo.getBeforeMultiDeleteActions());
        list.add(extendInfo.getMultiDeleteActions());
        list.add(extendInfo.getAfterMultiDeleteActions());

        //扩展操作
        for (VMActionCollection item : list) {

            for (ViewModelAction action : item) {
                if (action.getType() == ViewModelActionType.VMAction && ((MappedCdpAction)action).getIsGenerateComponent()) {
                    if (!InterActionCheck(action)) {
                        //MappedCdpActionComponentGenerator.Instance.GenerateComponent(action as MappedCdpAction, path, this.VMActionCode, this.AssemblyName, this.BizObjectID);
                        setNewCompActionCode(MappedCdpActionComponentGenerator.getInstance().GenerateComponent((MappedCdpAction)action , path, this.getVMActionCode(), this.getAssemblyName(), getNamespace(), this.getBizObjectID()));
                    }

                }
            }
        }
        // 帮助前
        for (ValueHelpConfig valueHelpConfig : viewModel.getValueHelpConfigs()) {
            if (valueHelpConfig.getHelpExtend() != null && valueHelpConfig.getHelpExtend().getBeforeHelp() != null) {

                for (ViewModelAction action : valueHelpConfig.getHelpExtend().getBeforeHelp()) {
                    if (action.getType() == ViewModelActionType.VMAction && ((MappedCdpAction)action).getIsGenerateComponent()) {
                        setNewCompActionCode(MappedCdpActionComponentGenerator.getInstance().GenerateComponent((MappedCdpAction)action, path, this.getVMActionCode(), this.getAssemblyName(), getNamespace(), this.getBizObjectID()));
                    }
                }
            }
        }

    }

    /**
     * 检查是否是内置动作，如果是内置动作返回值为true
     *
     * @param action
     * @return
     */
    private boolean InterActionCheck(ViewModelAction action) {
        boolean value = false;
        if (action.getID().equals("52479451-8e22-4751-8684-80489ce5786b")) {
            value = true; //CreateActions
        }
        if (action.getID().equals("47dd3752-72a3-4c56-81c0-ae8ccfe5eb98")) {
            value = true; //ModifyActions
        }
        if (action.getID().equals("5798f884-c222-47f4-8bbe-685c7013dee4")) {
            value = true; //ChangesetMappingActions
        }
        if (action.getID().equals("301c5991-a32d-4221-88bf-8c9d07bdd884")) {
            value = true; //ChangesetReversalMappingData
        }
        if (action.getID().equals("6fe68bfa-7c1b-4d6b-a7ef-14654168ae75")) {
            value = true; //QueryActions
        }
        if (action.getID().equals("42221ca3-9ee4-40af-89d2-ff4c8b466ac3")) {
            value = true; //DataMappingActions
        }
        if (action.getID().equals("991bf216-f55b-40bf-bb42-1b831b6ef3e9")) {
            value = true; //DataReversalMappingActions
        }
        if (action.getID().equals("7a02f472-5bbd-424b-9d9e-f82e3f9f448e")) {
            value = true; //RetrieveActions
        }
        if (action.getID().equals("9a17e935-7366-489d-b110-0ae103e5648e")) {
            value = true; //DeleteActions
        }
        if (action.getID().equals("7b1c3c4l-t1a4-4dyc-b75b-7695hcb3we7e")) {
            value = true; //MultiDeleteActions
        }
        return value;
    }

    private void setNewCompActionCode(String code) {
        if (!StringUtils.isEmpty(code)) {
            this.createComponentActionList.add(code);
        }
    }
}